import { useEffect } from "react";
import * as d3 from "d3";

const D3Array = () => {
  const adder = new d3.Adder();
  adder.add(42);
  console.log(adder.valueOf());
  adder.add(23);
  console.log(adder.valueOf());
  const rs = d3.fsum([0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]);
  console.log(rs);

  const athletes = [
    {
      name: "Floyd Mayweather",
      sport: "Boxing",
      nation: "United States",
      earnings: 285,
    },
    {
      name: "Lionel Messi",
      sport: "Soccer",
      nation: "Argentina",
      earnings: 111,
    },
    {
      name: "Cristiano Ronaldo",
      sport: "Soccer",
      nation: "Portugal",
      earnings: 108,
    },
    { name: "Conor McGregor", sport: "MMA", nation: "Ireland", earnings: 99 },
    { name: "Neymar", sport: "Soccer", nation: "Brazil", earnings: 90 },
    {
      name: "LeBron James",
      sport: "Basketball",
      nation: "United States",
      earnings: 85.5,
    },
    {
      name: "Roger Federer",
      sport: "Tennis",
      nation: "Switzerland",
      earnings: 77.2,
    },
    {
      name: "Stephen Curry",
      sport: "Basketball",
      nation: "United States",
      earnings: 76.9,
    },
    {
      name: "Matt Ryan",
      sport: "Football",
      nation: "United States",
      earnings: 67.3,
    },
    {
      name: "Matthew Stafford",
      sport: "Football",
      nation: "United States",
      earnings: 59.5,
    },
  ];

  const bin = d3.bin();
  const buckets = bin(d3.map(athletes, (d) => d.earnings));
  console.log(buckets);
  console.log(d3.max(athletes, (d) => d.earnings));

  const bin5 = d3.bin().thresholds([0, 2, 5, 10, 15]);
  console.log(bin5);

  const aSet = new Set(athletes.map((d) => d.nation));
  const aSet1 = new Set(d3.map(athletes, (d) => d.nation));
  console.log(aSet);
  console.log(aSet1);

  const bisector = d3.bisector((d: any) => d.earnings);
  console.log(bisector.right(athletes, 300));
  console.log(bisector.left(athletes, 300));
  console.log(bisector.center(athletes, 300));

  const athletesBySport = d3.group(athletes, (d) => d.sport);
  console.log(athletesBySport);
  console.log(athletesBySport.keys());
  console.log(athletesBySport.values());
  console.log(athletesBySport.get("Basketball"));

  // 索引字段不能有重复值
  // const indexedAthletes = d3.index(athletes, (d) => d.nation);
  // console.log(indexedAthletes);

  const athletesByNationSport = d3.group(
    athletes,
    (d) => d.nation,
    (d) => d.sport
  );
  console.log(Object.keys(athletesByNationSport));
  athletesByNationSport.forEach((item) => {
    console.log(item);
    console.log(Object.entries(item));
    console.log(item.keys());
  });
  console.log(athletesByNationSport.get("United States"));
  console.log(athletesByNationSport.get("United States")!.get("Boxing"));

  // 返回与d3.group()不一样的数据格式，仔细按需要使用
  // https://d3js.org/d3-array/intern
  // Interning values
  // The InternMap and InternSet classes extend the native JavaScript Map
  // and Set classes, respectively, allowing Dates and other non-primitive
  // keys by bypassing the SameValueZero algorithm when determining key equality.
  // d3.group, d3.rollup and d3.index use an InternMap rather than a native Map.
  // InternMap and InternSet扩展于标准库的Map和Set，主要为了让日期类型的值可以作为key使用。
  const flatGroupedAthletes = d3.flatGroup(
    athletes,
    (d) => d.nation,
    (d) => d.sport
  );
  console.log(flatGroupedAthletes);
  console.log(flatGroupedAthletes[0]);
  console.log(athletesByNationSport);
  console.log(athletesByNationSport.get("United States"));
  console.log(athletesByNationSport.get("United States")?.get("Basketball"));

  console.log(d3.ticks(1, 10, 5));
  console.log(d3.ticks(1, 10, 9));
  console.log(d3.tickIncrement(1, 10, 5)); // 计算步长
  console.log(d3.tickIncrement(1, 10, 9)); // 计算步长
  console.log(d3.tickStep(1, 10, 9));
  console.log(d3.tickStep(10, 1, 9));
  // console.log(d3.transpose(athletes)); // 入参必须是矩阵类型数据

  const rollupByLength = d3.rollup(
    athletes,
    (v) => v.length,
    (d) => d.sport
  );
  console.log(rollupByLength);

  const rollupByEarning = d3.rollup(
    athletes,
    (v) => d3.sum(v, (d) => d.earnings),
    (d) => d.sport
  );
  console.log(rollupByEarning);

  const byNationSport = d3.rollup(
    athletes,
    (v) => v.length,
    (d) => d.nation,
    (d) => d.sport
  );
  console.log(byNationSport);

  const transactions = [
    { name: "Jim", amount: 3400, date: new Date("2015-11-12") },
    { name: "Carl", amount: 12011, date: new Date("2015-11-12") },
    { name: "Carl", amount: 2391, date: new Date("2015-11-12") },
    { name: "Stacy", amount: 3405, date: new Date("2015-10-09") },
    { name: "Stacy", amount: 1201, date: new Date("2016-01-04") },
  ];
  const transactionsByDate = d3.group(transactions, (d) => d.date);
  console.log(transactionsByDate);

  useEffect(() => {}, []);

  return (
    <div>
      <table>
        <thead>
          <tr>
            <th>Sport</th>
            <th>Athletes</th>
          </tr>
        </thead>
        <tbody>
          {Array.from(athletesBySport, ([key, values]) => (
            <tr
              dangerouslySetInnerHTML={{
                __html: ` <tr>
              <td>${key}</td>
              <td>${values.map((d) => d.name).join(", ")}</td>
            </tr>`,
              }}
            />
          ))}
        </tbody>
      </table>
    </div>
  );
};

export default D3Array;
